﻿using System;
using System.Linq;
using System.Threading.Tasks;
using Bridge.Workflow.Domain;
using Bridge.Workflow.EntityFrameworkCore.Persistence;
using Users;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;
using WorkflowCore.Interface;
using WorkflowCore.Models;

namespace Bridge.Workflow.Application
{
    /// <summary>
    /// 通用审批
    /// </summary>
    public class GeneralAuditingStepBodyService : StepBody, ITransientDependency
    {
        private const string ActionName = "AuditEvent";
        //protected readonly INotificationPublisher _notificationPublisher;
        private readonly IAbpPersistenceProvider _abpPersistenceProvider;
        private readonly IUserService _currentUser;

        public GeneralAuditingStepBodyService(
            IAbpPersistenceProvider abpPersistenceProvider,
            IUserService currentUser)
        {
            this._abpPersistenceProvider = abpPersistenceProvider;
            this._currentUser = currentUser;
        }

        /// <summary>
        /// 审核人
        /// </summary>
        public string UserId { get; set; }

        /// <summary>
        /// 步骤执行逻辑处理
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override ExecutionResult Run(IStepExecutionContext context)
        {
            return ExecutionRunAsync(context).Result;
        }

        /// <summary>
        /// 生成审核记录
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task<ExecutionResult> ExecutionRunAsync(IStepExecutionContext context)
        {
            if (string.IsNullOrEmpty(UserId)) return ExecutionResult.Next();
            var userId = Guid.Empty;
            if (Guid.TryParse(UserId, out userId) == false) return ExecutionResult.Next();
            if (!context.ExecutionPointer.EventPublished)
            {
                var workflow = await _abpPersistenceProvider.GetPersistedWorkflow(context.Workflow.Id);
                var workflowDefinition = await _abpPersistenceProvider.GetPersistedWorkflowDefinition(context.Workflow.WorkflowDefinitionId, context.Workflow.Version);

                //var userIdentity = _currentUser.FirstOrDefault(u => u.Id == workflow.CreatorId);
                //if (userIdentity == null)
                //{
                //  return ExecutionResult.Next();
                //}

                //通知审批人
                //var notificationData = new NotificationData();
                //notificationData.Properties["content"] = $"【{userIdentityName}】提交的{workflowDefinition.Title}需要您审批！";
                //_notificationPublisher.PublishAsync("Task", notificationData,
                //    userIds: new UserIdentifier[] { new UserIdentifier(workflow.TenantId, UserId) },
                //     entityIdentifier: new EntityIdentifier(workflow.GetType(), workflow.Id)
                //    ).Wait();


                //添加审核人记录
                var auditUserResult = await _currentUser.GetUserById(userId);
                if (auditUserResult == null || auditUserResult.Code==0 )
                {
                    return ExecutionResult.Next();
                }
                var auditUser = auditUserResult.Result;
                var key = Guid.NewGuid().ToString();
                var result = await _abpPersistenceProvider.InsertAuditor(new PersistedWorkflowAuditor(key)
                {
                    WorkflowId = workflow.Id,
                    ExecutionPointerId = context.ExecutionPointer.Id,
                    Status = EnumAuditStatus.UnAudited,
                    UserId = auditUser.Id,
                    TenantId = workflow.TenantId,
                    UserIdentityName = auditUser.Name,
                    CreationTime = DateTime.Now,
                    Remark = string.Empty,
                    CreatorId = userId
                });

                DateTime effectiveDate = DateTime.MinValue;

                return ExecutionResult.WaitForEvent(ActionName, key, effectiveDate);
            }
            var pass = await _abpPersistenceProvider.AuditorAnyAsync(context.ExecutionPointer.Id, userId, EnumAuditStatus.Pass);
            if (!pass)
            {
                context.Workflow.Status = WorkflowStatus.Complete;
                return ExecutionResult.Next();
            }

            return ExecutionResult.Next();
        }
    }
}
